import time
import datetime
import pandas as pd
from xtquant import xtdata
from typing import Dict, Optional
import threading


class TradingVolumeCalculator:
    """交易总量计算器 - 使用降级策略"""

    def __init__(self):
        self.volume_cache = {}  # 缓存交易总量数据
        self.last_calculation_time = {}  # 记录每个股票上次计算时间
        self.calculation_interval = 300  # 5分钟 = 300秒
        self._lock = threading.Lock()

    def get_realtime_volume_from_minute(self, stock_code: str) -> Optional[Dict]:
        """
        使用分钟线数据获取实时累计交易量（交易时间内使用）

        Args:
            stock_code: 股票代码

        Returns:
            实时交易总量信息
        """
        try:
            # 获取当日分钟线数据
            today = datetime.datetime.now().strftime("%Y%m%d")
            data = xtdata.get_local_data(
                stock_list=[stock_code],
                period='1m',
                start_time=today,
                end_time=today
            )

            if not data or stock_code not in data:
                return None

            df = data[stock_code]
            if df.empty:
                return None

            # 计算累计成交量和成交额
            total_volume = df['volume'].sum() if 'volume' in df.columns else 0
            total_amount = df['amount'].sum() if 'amount' in df.columns else 0

            if total_amount <= 0:
                return None

            # 计算平均价格
            avg_price = total_amount / total_volume if total_volume > 0 else 0

            # 计算5分钟内跌幅
            decline_5min = self._calculate_5min_decline(df)

            result = {
                'stock_code': stock_code,
                'total_volume': int(total_volume),
                'total_amount': round(total_amount, 2),
                'total_amount_yi': round(total_amount / 100000000, 4),
                'avg_price': round(avg_price, 4),
                'decline_5min': decline_5min,
                'calculation_time': datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                'data_type': 'minute',
                'data_points': len(df)
            }

            return result

        except Exception as e:
            print(f"获取 {stock_code} 分钟线数据失败: {e}")
            return None

    def _calculate_5min_decline(self, df: pd.DataFrame) -> Optional[Dict]:
        """
        计算5分钟内跌幅

        Args:
            df: 分钟线数据DataFrame

        Returns:
            5分钟跌幅信息
        """
        try:
            if df.empty or len(df) < 2:
                return None

            # 确保数据按时间排序
            df_sorted = df.sort_index()
            
            # 获取最新的价格（最后一条记录）
            current_price = df_sorted.iloc[-1]['close'] if 'close' in df_sorted.columns else None
            
            # 获取5分钟前的价格
            # 如果数据不足5条，则使用第一条数据
            lookback_minutes = min(5, len(df_sorted) - 1)
            price_5min_ago = df_sorted.iloc[-(lookback_minutes + 1)]['close'] if 'close' in df_sorted.columns else None
            
            if current_price is None or price_5min_ago is None or price_5min_ago == 0:
                return None

            # 计算跌幅
            decline_amount = current_price - price_5min_ago
            decline_percent = (decline_amount / price_5min_ago) * 100

            return {
                'current_price': round(current_price, 4),
                'price_5min_ago': round(price_5min_ago, 4),
                'decline_amount': round(decline_amount, 4),
                'decline_percent': round(decline_percent, 4),
                'is_decline': decline_amount < 0,
                'lookback_minutes': lookback_minutes
            }

        except Exception as e:
            print(f"计算5分钟跌幅失败: {e}")
            return None

    def get_trading_volume(self, stock_code: str) -> Optional[Dict]:
        """
        获取交易量，使用降级策略

        Args:
            stock_code: 股票代码

        Returns:
            交易总量信息
        """
        current_time = time.time()
        
        # 检查缓存
        with self._lock:
            last_time = self.last_calculation_time.get(stock_code, 0)
            if current_time - last_time < self.calculation_interval:
                return self.volume_cache.get(stock_code)
        
        # 直接使用分钟线数据获取交易量
        result = self.get_realtime_volume_from_minute(stock_code)
        
        # 更新缓存
        if result:
            with self._lock:
                self.volume_cache[stock_code] = result
                self.last_calculation_time[stock_code] = current_time
        
        return result


# 全局实例
volume_calculator = TradingVolumeCalculator()


def get_stock_trading_volume(stock_code: str) -> Optional[Dict]:
    """
    获取股票交易量（便捷函数）

    Args:
        stock_code: 股票代码

    Returns:
        交易总量信息字典
    """
    return volume_calculator.get_trading_volume(stock_code)


# 使用示例
if __name__ == "__main__":
    # 测试股票代码
    stock_code = "513060.SH"  # 可以修改为您需要的股票代码
    
    print("=== 交易总量计算器使用示例 ===")
    print(f"测试股票: {stock_code}")
    print()
    
    # 获取交易总量
    print("获取交易总量...")
    volume_info = get_stock_trading_volume(stock_code)
    
    if volume_info:
        print(f"✅ 获取成功")
        print(f"   股票代码: {volume_info['stock_code']}")
        print(f"   成交量: {volume_info['total_volume']:,} 股")
        print(f"   成交额: {volume_info['total_amount']:,.2f} 元")
        print(f"   成交额: {volume_info['total_amount_yi']:.4f} 亿元")
        print(f"   平均价: {volume_info['avg_price']:.4f} 元")
        print(f"   计算时间: {volume_info['calculation_time']}")
        print(f"   数据来源: {volume_info.get('data_type', '未知')}")
        print(f"   数据点数: {volume_info.get('data_points', 0)}")
        
        # 显示5分钟跌幅信息
        decline_info = volume_info.get('decline_5min')
        if decline_info:
            print(f"\n   📊 5分钟跌幅信息:")
            print(f"   当前价格: {decline_info['current_price']:.4f} 元")
            print(f"   5分钟前价格: {decline_info['price_5min_ago']:.4f} 元")
            print(f"   价格变化: {decline_info['decline_amount']:+.4f} 元")
            print(f"   跌幅: {decline_info['decline_percent']:+.4f}%")
            print(f"   是否下跌: {'是' if decline_info['is_decline'] else '否'}")
            print(f"   回看分钟数: {decline_info['lookback_minutes']}")
        else:
            print(f"\n   📊 5分钟跌幅信息: 数据不足，无法计算")
    else:
        print("❌ 获取失败")
    
    print("\n" + "="*50)
    print("=== 使用说明 ===")
    print("1. 使用分钟线数据获取交易总量")
    print("2. 每5分钟自动更新一次")
    print("3. 支持缓存机制，避免重复计算")
    print("4. 成交额同时提供元和亿元两种单位")
    print("5. 线程安全，支持多线程环境")
    print("6. 新增5分钟内跌幅计算功能")
    print("7. 跌幅计算基于分钟线收盘价对比")
    print("8. 自动处理数据不足的情况")